#include "DRetangle.h"
#include <algorithm>
#include <cmath>

using namespace std;

#define _MIN( x, y ) ( x > y ? y : x )
#define _MAX( x, y ) ( x > y ? x : y )

/*****************************************************************
 *
 *
 *
 *****************************************************************/
DRetangle::DRetangle( double x1, double y1, double x2 , double y2)
{
	m_x1 = min( x1, x2 );
	m_y1 = min( y1, y2 );
	m_x2 = max( x1, x2 );
	m_y2 = max( y1, y2 );	
}


/*****************************************************************
 *
 *
 *
 *****************************************************************/
DRetangle::~DRetangle()
{


} 

/*****************************************************************
 *
 *
 *
 *****************************************************************/
bool DRetangle::contains( double px, double py )
{
	return px >= m_x1 && px <= m_x2 && 
	       py >= m_y1 && py <= m_y2; 
}


/*****************************************************************
 *
 *
 *
 *****************************************************************/
void DRetangle::extend( double px, double py )
{
	if( px < m_x1 )
		m_x1 = px;
	if( px > m_x2 )
		m_x2 = px;
	if( py < m_y1 )
		m_y1 = py;
	if( py > m_y2 )
		m_y2 = py;	
}

/*****************************************************************
 *
 *
 *
 *****************************************************************/
void DRetangle::extend( DRectangle &r )
{
	this->extend( r.m_x1, r.m_y1 );
	this->extend( r.m_x2, r.m_y2 );
}

/*****************************************************************
 *
 *
 *
 *****************************************************************/
bool DRectangle::isIntersect( DRectangle& that, double tolerance, double *distance )
{
	double xDiff = min( x2, that.x2 ) - max( x1, that.x1 );
	double yDiff = min( y2, that.y2 ) - max( y1, that.y1 );

	double dist = 0;
	bool intersect = false;

	if( xDiff >= 0 && yDiff >= 0 ) {
		intersect = true;
	}
	else if( xDiff < 0 && yDiff >= 0 ){
		dist = -xDiff;	
	}
	else if( xDiff >= 0 && yDiff < 0 ){
		dist = -yDiff;
	}
	else{
		dist = sqrt( xDiff * xDiff + yDiff * yDiff );	
	}
	
	if( !intersect && dist < tolerance ) 
		intersect = true;
	
	if( distance ) 
		*distance = dist;
		
	return intersect;
}

/*****************************************************************
 *
 *
 *
 *****************************************************************/
bool DRectangle::isIntersect2( DRectangle& that )
{

	//get max coordinates of the two lower left corners
	//get min coordinates of the two upper right corners
	double xDiff = min( m_x2, that.m_x2 ) - max( m_x1, that.m_x1 );
	double yDiff = min( m_y2, that.m_y2 ) - max( m_y1, that.m_y1 );

	bool intersect = false;	
	if( xDiff >= 0 && yDiff >= 0 ) 
		intersect = true;
		
	return intersect;	
}

/*****************************************************************
 *
 *
 *
 *****************************************************************/
ostream& operator<<( ostream& out, DRectangle& rectangle )
{
	out << "Rectangle: " 
				<< "( " << rectangle.m_x1 << ", " << rectangle.m_y1 << " )" 
				<< ","
				<< "( " << rectangle.m_x2 << ", " << rectangle.m_y2 << " )" 
				<< endl;
	return out;
}